---@class ClientFriendInfo
local FriendInfo = Class("FriendInfo")
function FriendInfo:ctor()
    self.getLoveState = EnumConst.LoveStateEnum.NONE;
    self.sendLoveState = EnumConst.LoveStateEnum.NORMAL;
end

function FriendInfo:UpdateByMsg(friendMsg)
    local protoInfo = friendMsg.info
    self.playerId = tostring(protoInfo.playerId);
    self.name = protoInfo.name;
    self.offlineTime = tostring(friendMsg.offlineTime);
    self.loveTime = 0;
    self.beLove = 0;
    self.level = protoInfo.level;
    self.star = protoInfo.star;
    self.picFrame = protoInfo.picFrame;
    self.pic = protoInfo.pic;
    self.modelId = protoInfo.modelId;
    self.maxPower = protoInfo.maxPower;
    self.dungeonId = protoInfo.dungeonId;
    self.background = protoInfo.background;
    self.partnerModelId = protoInfo.modelId;
    self.partnerId = tostring(protoInfo.playerId);
    self.petInfo = friendMsg.petInfo;
    self.lbs = protoInfo.lbs or ""
    self.leaveMsg = friendMsg.leaveMsg
    
    --是否已赠送爱心
    if friendMsg.giveLove == 1 then
        self.sendLoveState = EnumConst.LoveStateEnum.USED
    else
        self.sendLoveState = EnumConst.LoveStateEnum.NORMAL
    end
    --是否有可接收的爱心
    if friendMsg.receivedLove == 1 then
        --是否已领取
        self.getLoveState = EnumConst.LoveStateEnum.USED
    elseif friendMsg.receiveLove == 1 then
        self.getLoveState = EnumConst.LoveStateEnum.NORMAL
    else
        self.getLoveState = EnumConst.LoveStateEnum.NONE
    end
end
function FriendInfo:GetReason()
    if self.recommendReason then
        return self.recommendReason
    end
    local str = dataTable.getDataTableByStringId("t_global", "194", "f_string_value")
    local t = string.split2number(str, ",")
    local index = math.random(1, #t)
    local reason
    if t[index] < 10 then
        reason = getLanguage("FriendRecommend0" .. t[index])
    else
        reason = getLanguage("FriendRecommend" .. t[index])
    end
    self.recommendReason = reason
    return reason
end
---@class ClientFriendGift
local FriendGiftInfo = Class("FriendGiftInfo")
function FriendGiftInfo:UpdateByMsg(msgDB)
    self.id = tostring(msgDB.giftID)
    self.endTime = tonumber(tostring(msgDB.endTime))
    self.isGet = msgDB.isGet == 1 and true or false
    self.modelId = tonumber(tostring(msgDB.modelId))
    self.playerName = msgDB.playerName
    self.f_Type = dataTable.getDataTableByStringId("t_friendygift", self.modelId, "f_Type")
    self.serial = msgDB.serial
    --self.type = msgDB.type
    --self.param = msgDB.param
end

---@class FriendManager
FriendManager = {
    friendGiftLevel = 1, --社交等级
    friendGiftExp = 0, --社交当前经验
    friendGiftPoint = 0, --宝箱点数
    friendGiftSocialBoxLevel = 0, --已领取的社交宝箱对应的等级
    friendCompeteBattleInfo = {}, --切磋信息
    friendCompeteBattleType = EnumConst.FightTypeConst.FriendCompeteBattle;
    --friendCompeteBattleHistoryInfo = {},--切磋历史信息
    ---@type ClientFriendGift[]
    friendGiftInfoList = {},
    MAX_FRIEND_COUNT = 100,
    blackPidList = {},
}
local t = FriendManager

G.serverData = G.serverData or {};
--region 好友
function t.ClearFriend()
    G.serverData["friendInfo"] = G.serverData["friendInfo"] or {};
    G.serverData["friendInfo"]["recommend"] = {}
    G.serverData["friendInfo"]["myFriend"] = {}
    G.serverData["friendInfo"]["applyFriend"] = {}
    G.serverData["friendInfo"]["find"] = {}
end
function t.ClearFriendByType(friendType)
    local list = FriendManager.GetFriendList(friendType)
    if list == nil then
        return
    end
    table.clear(list)
end
function t.ClearRecommend()
    G.serverData["friendInfo"] = G.serverData["friendInfo"] or {};
    G.serverData["friendInfo"]["recommend"] = {}
end
function t.AddFriend(friendType, friendDB)
    local list = FriendManager.GetFriendList(friendType)
    if list then
        local friend = FriendInfo.New()
        friend:UpdateByMsg(friendDB)
        list[friend.playerId] = friend
        list[friend.playerId].petInfo = friendDB.petInfo;
    end
end
function t.AddFriend2(friendType, friendInfo)
    local list = FriendManager.GetFriendList(friendType)
    if list and friendInfo then
        list[friendInfo.playerId] = friendInfo
    end
end
function t.UpdateFriend(friendType, friendDB)
    local friend = FriendManager.GetFriend(friendType, friendDB.info.playerId)
    if friend then
        friend:UpdateByMsg(friendDB)
    end
end
function t.DeleteFriend(friendType, friendId)
    friendId = tostring(friendId)
    local list = FriendManager.GetFriendList(friendType)
    if list then
        list[friendId] = nil
    end
    --删除申请拟变列表内的的消息
    logicMgr.PetManager.RemoveOthersApplyByPlayerId(friendId)

    if PetManager.myApply and PetManager.myApply.toPlayerId then
        local applyInfo = PetManager.myApply;
        local local_apply_playid = tostring(PetManager.myApply.toPlayerId)
        local applyInfo = PetManager.myApply;
        if local_apply_playid == friendId then
            if table.getn(applyInfo) ~= 0 then
                local param = {}
                param.tmplPetId = applyInfo.templatePetInfo.petId
                param.mutatePetId = applyInfo.mutatePetInfo.petId
                PetManager.ResCancelMating(param)
            else
            end

            if isOpenUI(PanelResNames.Page_PetApplyMyRequest) then
                DestoryUI(PanelResNames.Page_PetApplyMyRequest)
            end
            if isOpenUI(PanelNames.UIPetFriendList) then
                local ui_pet_friend_list = CtrlManager.GetCtrl(PanelNames.UIPetFriendList)
                if ui_pet_friend_list ~= nil then
                    ui_pet_friend_list:refreshPanel()
                end
            end
        end
    end

end
---@return ClientFriendInfo[]
function t.GetFriendList(friendType)
    local f = G.serverData["friendInfo"]
    if not f then
        return {}
    end
    if friendType == EnumConst.FriendType.myFriend then
        return f["myFriend"]
    elseif friendType == EnumConst.FriendType.recommend then
        return f["recommend"]
    elseif friendType == EnumConst.FriendType.applyFriend then
        return f["applyFriend"]
    elseif friendType == EnumConst.FriendType.find then
        return f["find"]
    end
    return {}
end
function t.GetFindFriend()
    local list = t.GetFriendList(EnumConst.FriendType.find)
    if list == nil then
        return nil
    end
    for k, v in pairs(list) do
        return v
    end
    return nil
end
function t.GetMyFriendList()
    return t.GetFriendList(EnumConst.FriendType.myFriend)
end
function t.FriendChapterInfo()
    local friendList = t.GetMyFriendList()
    if table.getn(friendList) <= 0 then
        return false
    end
    local maxNum = G.dataTable["t_global"]["191"]["f_int_value"] or 10
    local info = {}
    local info1 = {}
    local mapId = logicMgr.MapManager.getMapId()
    local current = G.dataTable["t_stage"][tostring(mapId)];
    local curChapterId = current.f_ChapterId
    if friendList then
        for _, v in pairs(friendList) do
            local friendCur = G.dataTable["t_stage"][tostring(v.dungeonId)];
            if friendCur then
                if friendCur.f_ChapterId >= curChapterId then
                    local data = {}
                    data["pic"] = v.pic
                    data["picFrame"] = v.picFrame
                    data["name"] = v.name
                    data["stageName"] = friendCur.f_ChapterId .. "-" .. friendCur.f_StageNum;
                    data["stageId"] = v.dungeonId
                    if friendCur.f_ChapterId == curChapterId then
                        if #info < maxNum then
                            table.insert(info, data)
                        end
                    else
                        if #info1 < maxNum then
                            table.insert(info1, data)
                        end
                    end
                end
            end
        end
    end
    return info, info1
end
function t.GetMyFriendNewList()
    local list = t.GetMyFriendList()
    local temp = {}
    for k, v in pairs(list) do
        table.insert(temp, v)
    end
    return temp
end
function t.GetFriend(type, id)
    id = tostring(id)
    local list = t.GetFriendList(type)
    if list then
        return list[id]
    end
    return nil
end
---@return ClientFriendInfo
function t.GetMyFriend(id)
    return t.GetFriend(EnumConst.FriendType.myFriend, id)
end
function t.SetFriendGetLoveState(id, state)
    id = tostring(id)
    local info = t.GetMyFriend(id)
    if info then
        info.getLoveState = state
    end
end
function t.SetFriendSendLoveState(id, state)
    id = tostring(id)
    local info = t.GetMyFriend(id)
    if info then
        info.sendLoveState = state
    end
end
function t.SetFriendShip(friendship)
    G.serverData["friendInfo"]["friendship"] = friendship
end
function t.SetTodayFriendShip(todayCount)
    G.serverData["friendInfo"]["todayFriendShip"] = todayCount
end
function t.GetTodayFriendShip()
    if not G.serverData["friendInfo"] then
        return 0
    end
    return G.serverData["friendInfo"]["todayFriendShip"] or 0
end
function t.IsMaxFriendShipToday()
    local count = t.GetTodayFriendShip()
    if count >= 30 then
        return true
    end
    return false
end
function t.IsMaxFriend()
    local list = t.GetMyFriendList()
    if list == nil then
        return false
    end
    if table.getn(list) >= t.MAX_FRIEND_COUNT then
        return true
    end
    return false
end
function t.IsFriend(friendId)
    friendId = tostring(friendId)
    local info = t.GetMyFriend(friendId)
    return info ~= nil
end
function t.IsFriendByName(name)
    local list = t.GetMyFriendList()
    for k, v in pairs(list) do
        if v.name == name then
            return true
        end
    end
    return false
end
--endregion 好友
--region 好友礼物功能
--大宝箱
function t.GetBigBoxCfg()
    local cfg = dataTable.getDataTable("t_friendybox")
    local id = 1
    for k, v in pairs(cfg) do
        if v.f_FriendyLv <= t.friendGiftLevel then
            id = math.max(id, k)
        end
    end
    return cfg[id]
end
function t.ClearFriendGiftInfoList()
    table.clear(t.friendGiftInfoList)
end
function t.AddFriendGiftInfo(db)
    local info = FriendGiftInfo.New()
    info:UpdateByMsg(db)
    t.friendGiftInfoList[info.id] = info
end
function t.UpdateFriendGiftInfo(db)
    local id = tostring(db.giftID)
    local info = t.friendGiftInfoList[id]
    if info then
        info:UpdateByMsg(db)
    end
end
function t.DeleteFriendGiftInfo(id)
    id = tostring(id)
    t.friendGiftInfoList[id] = nil
end
function t.UpdateFriendGift(level, exp, point)
    t.friendGiftLevel = math.max(level, 1)
    t.friendGiftExp = exp
    t.friendGiftPoint = point
end
--已领取的社交宝箱对应的等级
function t.UpdateFriendGiftSocialBoxLevel(level)
    t.friendGiftSocialBoxLevel = math.max(level, 1)
end
function t.HasRareList()
    local data = dataTable.getDataTable("t_friendygift")
    for k, v in pairs(t.friendGiftInfoList) do
        local d = data[v.modelId]
        if d and d.f_Type == 2 then
            return true
        end
    end
    return false
end
---type nil:都检查  1:普通   2:稀有
function t.HasReward(type)
    local time = HelperFunc.GetServerTime()
    for k, v in pairs(t.friendGiftInfoList) do
        local ctype = dataTable.getDataTableById("t_friendygift", v.modelId, "f_Type")
        if ctype and ctype == type or type == nil then
            if not v.isGet and v.endTime > time then
                return true
            end
        end
    end
    return false
end
function t.CanOpenFriendBox()
    --大宝箱
    local cfg = logicMgr.FriendManager.GetBigBoxCfg()
    local cur = logicMgr.FriendManager.friendGiftPoint
    local max = cfg.f_FriendyKey
    if (cfg and cur >= max) then
        return true
    else
        return false
    end
end
---type 1:普通   2:稀有
---@return FriendGiftItemData[]
function t.GetFriendGiftList(type, list)
    table.clear(list)
    local data = dataTable.getDataTable("t_friendygift")
    for k, v in pairs(t.friendGiftInfoList) do
        --local d = data[v.modelId]
        --if d and d.f_Type == type then
        table.insert(list, v)
        --end
    end
end
--endregion 好友礼物功能
--获得好友切磋信息
function t.GetFriendCompeteBattleInfo()
    return friendCompeteBattleInfo or {}
end
--修改好友切磋信息
function t.SetFriendCompeteBattleInfo(msg)
    friendCompeteBattleInfo = {}
    friendCompeteBattleInfo.formation = msg.formation;
    friendCompeteBattleInfo.friendId = msg.friendId;
    friendCompeteBattleInfo.supportSkill = msg.supportSkill;
    friendCompeteBattleInfo.winTimes = msg.winTimes;
    friendCompeteBattleInfo.competeTimes = msg.competeTimes;

    if msg and msg.playerFormation and #msg.playerFormation then
        local formation = {}
        for i = 1, #msg.playerFormation do
            table.insert(formation, msg.playerFormation[i].partnerId)
        end
        logicMgr.FormationManager.SetFormation(EnumConst.FormationType.FriendCompeteBattle, formation);
    end
end
--设置好友切磋类型
function t.SetFriendCompeteBattleType(type)
    friendCompeteBattleType = type;
end
--获取好友切磋类型
function t.GetFriendCompeteBattleType()
    return friendCompeteBattleType;
end

--获取黑名单
function t.GetBlackList(isPid)
    if isPid then
        return t.blackPidList
    else
        return t.blackInfoList
    end
end

function t.SetBlackInfoList(list)
    t.blackInfoList = list

    FireEvent(Config.EventType.Black_list_refresh)
end

function t.SetBlackList(blackList)
    local ls = {}
    for k,v in pairs(blackList) do
        table.insert(ls, tostring(v))
    end
    t.blackPidList = ls
end

--操作黑名单玩家
function t.OperateBlackPlayer(pid, type)
    local index = 0
    
    if type == 1 then
        table.insert(t.blackPidList, tostring(pid))
        FireEvent(Config.EventType.Black_add_refresh)
    else
        for i=1, table.getn(t.blackPidList) do
            if t.blackPidList[i] == tostring(pid) then
                index = i
                break
            end
        end
        if index > 0 then
            table.remove(t.blackPidList, index)
            FireEvent(Config.EventType.Black_add_refresh)
        end
        
        index = 0
        for i=1, table.getn(t.blackInfoList) do
            if tostring(t.blackInfoList[i].playerId) == tostring(pid) then
                index = i
                break
            end
        end
        if index > 0 then
            table.remove(t.blackInfoList, index)
        end
        FireEvent(Config.EventType.Black_list_refresh)
    end
end

function t.IsInBlack(pid)
    local have = false
    for _,v in pairs(t.blackPidList) do
        if v == tostring(pid) then
            have = true
            break
        end
    end
    return have
end

function t.GetBlackMax()
    if t.blackMaxCount == nil then
        t.blackMaxCount = GetGlobalIntValue(627)
    end

    return t.blackMaxCount, table.getn(t.blackPidList)
end

function t.BlackIsEmpty()
    local count = 0
    if t.blackPidList then
        count = #t.blackPidList
    end
    return count == 0
end
----获得好友切磋历史战斗消息
--function t.GetFriendCompeteBattleHistory()
--    return friendCompeteBattleHistoryInfo or {}
--end
----修改好友切磋历史战斗消息
--function t.SetFriendCompeteBattleHistory(msg)
--
--end

return FriendManager

